home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl2 / examples / porting / glxsimple.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  6.9 KB  |  246 lines

  1. /*
  2.  * Copyright 1993, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. /* glxsimple.c - a simple program to show how to set up an X 
  19.  * window for OpenGL rendering
  20.  * Original code by Mark Kilgard.
  21.  * Modified to exit when the ESCAPE key is pressed.
  22.  * compile: cc -o glxsimple glxsimple.c -lGL -lX11 
  23.  */
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <GL/glx.h>        /* this includes the necessary X headers */
  27. #include <GL/gl.h>
  28. #include <X11/keysym.h>
  29.  
  30. static int snglBuf[] = {
  31.     GLX_RGBA, GLX_DEPTH_SIZE, 16, None};
  32. static int dblBuf[] = {
  33.     GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None};
  34.  
  35. Display        *dpy;
  36. Window          win;
  37. GLfloat         xAngle = 42.0, yAngle = 82.0, zAngle = 112.0;
  38. GLboolean    doubleBuffer = GL_TRUE;
  39.  
  40. void
  41. fatalError(char *message)
  42. {
  43.     fprintf(stderr, "glxsimple: %s\n", message);
  44.     exit(1);
  45. }
  46.  
  47. void
  48. redraw(void)
  49. {
  50.     static GLboolean   displayListInited = GL_FALSE;
  51.  
  52.     if (displayListInited) {
  53.         /* if display list already exists, just execute it */
  54.         glCallList(1);
  55.     } else {
  56.  
  57.         /* otherwise compile and execute to create the display list */
  58.         glNewList(1, GL_COMPILE_AND_EXECUTE);
  59.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  60.  
  61.         /* front face */
  62.         glBegin(GL_QUADS);
  63.             glColor3f(0.0, 0.7, 0.1);    /* green */
  64.             glVertex3f(-1.0, 1.0, 1.0);
  65.             glVertex3f(1.0, 1.0, 1.0);
  66.             glVertex3f(1.0, -1.0, 1.0);
  67.             glVertex3f(-1.0, -1.0, 1.0);
  68.  
  69.             /* back face */
  70.             glColor3f(0.9, 1.0, 0.0);    /* yellow */
  71.             glVertex3f(-1.0, 1.0, -1.0);
  72.             glVertex3f(1.0, 1.0, -1.0);
  73.             glVertex3f(1.0, -1.0, -1.0);
  74.             glVertex3f(-1.0, -1.0, -1.0);
  75.  
  76.             /* top side face */
  77.             glColor3f(0.2, 0.2, 1.0);    /* blue */
  78.             glVertex3f(-1.0, 1.0, 1.0);
  79.             glVertex3f(1.0, 1.0, 1.0);
  80.             glVertex3f(1.0, 1.0, -1.0);
  81.             glVertex3f(-1.0, 1.0, -1.0);
  82.  
  83.             /* bottom side face */
  84.             glColor3f(0.7, 0.0, 0.1);    /* red */
  85.             glVertex3f(-1.0, -1.0, 1.0);
  86.             glVertex3f(1.0, -1.0, 1.0);
  87.             glVertex3f(1.0, -1.0, -1.0);
  88.             glVertex3f(-1.0, -1.0, -1.0);
  89.         glEnd();
  90.         glEndList();
  91.         displayListInited = GL_TRUE;
  92.     }
  93.     if (doubleBuffer)
  94.         glXSwapBuffers(dpy, win);/* buffer swap does implicit glFlush */
  95.     else 
  96.         glFlush();    /* explicit flush for single buffered case */
  97. }
  98.  
  99. void
  100. main(int argc, char **argv)
  101. {
  102.     XVisualInfo    *vi;
  103.     Colormap        cmap;
  104.     XSetWindowAttributes swa;
  105.     GLXContext      cx;
  106.     XEvent          event;
  107.     GLboolean       needRedraw = GL_FALSE, recalcModelView = GL_TRUE;
  108.     int        dummy;
  109.  
  110.     /*** (1) open a connection to the X server ***/
  111.  
  112.     dpy = XOpenDisplay(NULL);
  113.     if (dpy == NULL) fatalError("could not open display");
  114.  
  115.     /*** (2) make sure OpenGL's GLX extension supported ***/
  116.  
  117.     if(!glXQueryExtension(dpy, &dummy, &dummy))
  118.         fatalError("X server has no OpenGL GLX extension");
  119.  
  120.     /*** (3) find an appropriate visual ***/
  121.  
  122.     /* find an OpenGL-capable RGB visual with depth buffer */
  123.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
  124.     if (vi == NULL) {
  125.         vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
  126.         if (vi == NULL) fatalError("no RGB visual with depth buffer");
  127.         doubleBuffer = GL_FALSE;
  128.     }
  129.     if(vi->class != TrueColor)
  130.         fatalError("TrueColor visual required for this program");
  131.  
  132.     /*** (4) create an OpenGL rendering context  ***/
  133.  
  134.     /* create an OpenGL rendering context */
  135.     cx = glXCreateContext(dpy, vi, /* no shared dlists */ None,
  136.         /* direct rendering if possible */ GL_TRUE);
  137.     if (cx == NULL)
  138.         fatalError("could not create rendering context");
  139.  
  140.     /*** (5) create an X window with the selected visual ***/
  141.  
  142.     /* create an X colormap since probably not using default visual */
  143.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, 
  144.         AllocNone);
  145.     swa.colormap = cmap;
  146.     swa.border_pixel = 0;
  147.     swa.event_mask = KeyPressMask |
  148.         ExposureMask | ButtonPressMask | StructureNotifyMask;
  149.     win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 
  150.         300, 300, 0, vi->depth, InputOutput, vi->visual, 
  151.         CWBorderPixel | CWColormap | CWEventMask, &swa);
  152.     XSetStandardProperties(dpy, win, "glxsimple", "glxsimple", None, 
  153.         argv, argc, NULL);
  154.  
  155.     /*** (6) bind the rendering context to the window ***/
  156.  
  157.     glXMakeCurrent(dpy, win, cx);
  158.  
  159.     /*** (7) request the X window to be displayed on the screen ***/
  160.  
  161.     XMapWindow(dpy, win);
  162.  
  163.     /*** (8) configure the OpenGL context for rendering ***/
  164.  
  165.     glEnable(GL_DEPTH_TEST); /* enable depth buffering */
  166.     glDepthFunc(GL_LESS);    /* pedantic, GL_LESS is the default */
  167.     glClearDepth(1.0);       /* pedantic, 1.0 is the default */
  168.  
  169.     /* frame buffer clears should be to black */
  170.     glClearColor(0.0, 0.0, 0.0, 0.0);
  171.  
  172.     /* set up projection transform */
  173.     glMatrixMode(GL_PROJECTION);
  174.     glLoadIdentity();
  175.     glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10.0);
  176.     /* establish initial viewport */
  177.     /* pedantic, full window size is default viewport */
  178.     glViewport(0, 0, 300, 300);
  179.  
  180.     printf( "Press left mouse button to rotate around X axis\n" );
  181.     printf( "Press middle mouse button to rotate around Y axis\n" );
  182.     printf( "Press right mouse button to rotate around Z axis\n" );
  183.  
  184.     /*** (9) dispatch X events ***/
  185.  
  186.     while (1) {
  187.         do {
  188.             XNextEvent(dpy, &event);
  189.             switch (event.type) {
  190.             case KeyPress: {
  191.                 KeySym        keysym;
  192.                 XKeyEvent     *kevent;
  193.                 char         buffer[1];
  194.                 /* It is necessary to convert the keycode to a 
  195.                  * keysym before checking if it is an escape */
  196.                 kevent = (XKeyEvent *) &event;
  197.                 if (XLookupString((XKeyEvent *)&event,buffer,1,&keysym,NULL) == 1 
  198.                     && keysym == (KeySym)XK_Escape)
  199.                     exit(0);
  200.                 break;
  201.             }
  202.             case ButtonPress:
  203.                 recalcModelView = GL_TRUE;
  204.                 switch (event.xbutton.button) {
  205.                 case 1: xAngle += 10.0; 
  206.                     break;
  207.                 case 2: yAngle += 10.0; 
  208.                     break;
  209.                 case 3: zAngle += 10.0; 
  210.                     break;
  211.                 }
  212.                 break;
  213.             case ConfigureNotify:
  214.                 glViewport(0, 0, event.xconfigure.width, 
  215.                     event.xconfigure.height);
  216.                 /* fall through... */
  217.             case Expose:
  218.                 needRedraw = GL_TRUE;
  219.                 break;
  220.             }
  221.         } while(XPending(dpy)); /* loop to compress events */
  222.  
  223.         if (recalcModelView) {
  224.             glMatrixMode(GL_MODELVIEW);
  225.  
  226.             /* reset modelview matrix to the identity matrix */
  227.             glLoadIdentity();
  228.  
  229.             /* move the camera back three units */
  230.             glTranslatef(0.0, 0.0, -3.0);
  231.  
  232.             /* rotate by X, Y, and Z angles */
  233.             glRotatef(xAngle, 0.1, 0.0, 0.0);
  234.             glRotatef(yAngle, 0.0, 0.1, 0.0);
  235.             glRotatef(zAngle, 0.0, 0.0, 1.0);
  236.  
  237.             recalcModelView = GL_FALSE;
  238.             needRedraw = GL_TRUE;
  239.         }
  240.         if (needRedraw) {
  241.             redraw();
  242.             needRedraw = GL_FALSE;
  243.         }
  244.     }
  245. }
  246.